// *************************************************************************************************
//
// MK3D Engine
// --------------------------------------
// Copyright (C) 2007-2011 Zeb (mailto: zebbey@gmail.com)
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// *************************************************************************************************

#ifndef __H_MK_MATERIAL__
#define __H_MK_MATERIAL__

#include "mk_render_define.h"
#include "mk_texture_mapping.h"

namespace MK3DE
{
	class CMPAmbient;
	class CMPDiffuse;
	class CMPSpecular;
	class CMPAlphaBlend;
	class CMPAlphaTest;
	class CMPCullingMode;
	class CMPDepthState;
	class CScene;
	class CMaterialProperty;
	class CShader;
	class CMPFog;

	class MK3DE_API CMaterial : public CTextureMapping
	{
	private:
		//! global properties.
		static CMPFog* _s_fogProperty;

	public:
		static BOOL Create();
		static void Destroy();

		//! Get global material properties.
		static CMPFog* GetFogProperty();

	public:
		CMaterial();
		~CMaterial();

		//! Create all material properties.
		BOOL CreateAllProperties();

		//! Load material from file.
		BOOL LoadFromFile(const char* name);

		//! Get material file name
		std::string GetFileName() { return _fileName; }

		//! Get shader constant properties.
		CMPAmbient* GetAmbientProperty();
		CMPDiffuse* GetDiffuseProperty();
		CMPSpecular* GetSpecularProperty();

		//! Get render state properties.
		CMPAlphaBlend* GetAlphaBlendProperty();
		CMPAlphaTest* GetAlphaTestProperty();
		CMPCullingMode* GetCullingModeProperty();
		CMPDepthState* GetDepthStateProperty();

		//! Set material and restore material.
		void SetMaterial(CScene* pScene, CShader* pShader, BOOL bShadow);
		void RestoreMaterial();

		//! Generate technique postfix.
		std::string GenerateTechniquePostfix(BOOL bShadowRecv);

	private:
		void __CleanTextureMapping();
		void __Clean();

	private:
		enum SHADER_CONSTANT_PROPERTY
		{
			SCP_AMBIENT = 0,
			SCP_DIFFUSE,
			SCP_SPECULAR,

			SCP_MAX,
		};

		enum RENDER_STATE_PROPERTY
		{
			RSP_ALPHA_BLEND = 0,
			RSP_ALPHA_TEST,
			RSP_CULLING_MODE,
			RSP_DEPTH_STATE,

			RSP_MAX,
		};

	private:
		std::string _fileName;

		CMaterialProperty* _shaderConstantProperties[SCP_MAX];
		CMaterialProperty* _renderStateProperties[RSP_MAX];

		std::ostringstream _techPostfix;

	};
}

#endif // __H_MK_MATERIAL__